home *** CD-ROM | disk | FTP | other *** search
- #!/bin/sh
- :; exec /usr/local/bin/stk -f "$0" "$@"
- ;;;
- ;;; STkTurtle v1.0
- ;;;
- ;;; A (direct) rewritting of the TkTurtle demo found on the net in STk.
- ;;; Original copyright:
- ;;; Copyright 1993 James Noble, kjx@comp.vuw.ac.nz
- ;;;
-
- ;;; This file comports two distinct parts.
- ;;; First part is the turtle package
- ;;; Second parts contains a set of examples using the turtle package
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;
- ;;;; T u r t l e p a c k a g e
- ;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (define turtle-canvas-name ".c")
- (define turtle-canvas '())
-
- (define turtle-colours #("" "root_weave" "stipple" "gray1" "boxes"
- "hlines2" "vlines2" "cross_weave"
- "light_gray" "dimple1" "vlines3" "hlines3"
- "grid4" "gray3" "dimple3" "grid8"))
-
- (define turtle-num_colours 16)
-
- (define turtle-d2r (/ 180 3.14159))
-
- (define turtle-x 0)
- (define turtle-y 0)
- (define turtle-direction 270)
- (define turtle-width 0)
- (define turtle-colour 0)
- (define turtle-pen #t)
-
- (define turtle-speed #t)
- (define turtle-show #t)
-
-
- ;;;
- ;;; initialise turtle
- ;;;
- (define (turtle)
- ;; clear actually does this, plus draw-turtle
- (set! turtle-x 0)
- (set! turtle-y 0)
- (set! turtle-direction 270)
- (set! turtle-width 0)
- (set! turtle-colour 0)
- (set! turtle-pen #t)
-
- ;; debugging
- (set! turtle-speed #t)
- (set! turtle-show #t)
-
- (if (winfo 'exists turtle-canvas-name)
- (new)
- (begin
- (scrollbar ".v" :relief "sunken" :borderwidth 3
- :command (lambda l (apply turtle-canvas 'yview l)))
- (scrollbar ".h" :relief "sunken" :borderwidth 3
- :orient 'horiz :command (lambda l
- (apply turtle-canvas 'xview l)))
-
- (canvas turtle-canvas-name :borderwidth 3
- :scrollregion '(-1000 -1000 1000 1000)
- :xscrollcommand (lambda l (apply .h 'set l))
- :yscrollcommand (lambda l (apply .v 'set l))
- :height 500
- :width 500)
-
- (set! turtle-canvas (string->widget turtle-canvas-name))
-
- (centre)
-
- (pack .h :side "bottom" :fill "x")
- (pack .v :side "right" :fill "y")
- (pack turtle-canvas :expand #t :fill "both")
-
-
- (bind turtle-canvas "<2>" (lambda (x y)
- (turtle-canvas 'scan 'mark x y)))
- (bind turtle-canvas "<B2-Motion>" (lambda (x y)
- (turtle-canvas 'scan 'dragto x y)))
- (bind turtle-canvas "<c>" centre)
- (bind turtle-canvas "<Control-c>" (lambda () (destroy ".")))
- (bind turtle-canvas "<Control-q>" (lambda () (destroy ".")))
- (bind turtle-canvas "<f>" toggle-speed)
- (bind turtle-canvas "<s>" toggle-show)
-
- (focus turtle-canvas)
-
- (wm 'minsize "." 10 10)
- (wm 'title "." "Turtle")
- (wm 'iconname "." "Turtle")
-
- (draw-turtle))))
-
- ;;;
- ;;; drawing
- ;;;
-
- (define (make-stipple n)
- (let ((name (vector-ref turtle-colours n)))
- (if (string=? name "")
- ""
- (string-append "@" *STk-library* "/images/" name))))
-
- (define (go length)
- (let ((newx (+ turtle-x (* (cos (/ turtle-direction turtle-d2r)) length)))
- (newy (+ turtle-y (* (sin (/ turtle-direction turtle-d2r)) length))))
-
- (goto newx newy)
- length))
-
- (define (goto x y)
- (when turtle-pen
- (turtle-canvas 'create 'line turtle-x turtle-y x y
- :width turtle-width
- :stipple (make-stipple turtle-colour)
- :tags 'line))
-
- (set! turtle-x x)
- (set! turtle-y y)
- (when turtle-show (draw-turtle))
- (when turtle-speed (update))
- (list x y))
-
-
- ;;; writing text
- (define (Write text)
- (turtle-canvas 'create 'text turtle-x turtle-y
- :text text
- :stipple (make-stipple turtle-colour)
- :tags 'text)
- (when turtle-speed (update)))
-
-
- ;;; writing windows
- (define (window name)
- (turtle-canvas 'create 'window turtle-x turtle-y
- :window name
- :tags 'window)
- (update))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; drawing parameters
- ;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;; change pen state
- (define (pen . p)
- (if (null? p)
- turtle-pen
- (set! turtle-pen (car p))))
-
- (define (down) (pen #t))
- (define (up) (pen #f))
-
-
- ;;; change direction
- (define (turn n)
- (turnto (+ turtle-direction n)))
-
- (define (turnto n)
- (set! turtle-direction (modulo (floor n) 360))
- (draw-turtle)
- turtle-direction)
-
- (define (east) (turnto 0))
- (define (south) (turnto 90))
- (define (west) (turnto 180))
- (define (north) (turnto 270))
-
- (define (direction)
- turtle-direction)
-
- (define (location)
- (list turtle-x turtle-y))
-
- (define (width . w)
- (unless (null? w)
- (set! turtle-width (car w))
- (draw-turtle))
- turtle-width)
-
- (define (colour . c)
- (if (null? c)
- turtle-colour
- (set! turtle-colour (modulo (floor (car c)) turtle-num_colours))))
-
- (define (status . c)
- (if (null? c)
- (list turtle-x turtle-y turtle-direction turtle-width turtle-colour
- turtle-pen)
- (if (not (= (length (car c)) 6))
- (error "Can't restore saved state")
- (let ((c (car c)))
- (set! turtle-x (list-ref c 0))
- (set! turtle-y (list-ref c 1))
- (set! turtle-direction (list-ref c 2))
- (set! turtle-width (list-ref c 3))
- (set! turtle-colour (list-ref c 4))
- (set! turtle-pen (list-ref c 5))
- (draw-turtle)
- c))))
-
- (define (draw-turtle)
- (when turtle-show
- (turtle-canvas 'delete 'turtle)
- (turtle-canvas 'create 'line
- turtle-x
- turtle-y
- (+ turtle-x (* (cos (/ turtle-direction turtle-d2r)) 10))
- (+ turtle-y (* (sin (/ turtle-direction turtle-d2r)) 10))
- :arrow 'last
- :fill "red"
- :tags 'turtle
- :width turtle-width))
- 0)
-
- (define (show)
- (set! turtle-show #t)
- (draw-turtle)
- #t)
-
- (define (hide)
- (set! turtle-show #f)
- (turtle-canvas 'delete 'turtle)
- #f)
-
- (define (toggle-show)
- (if turtle-show (hide) (show)))
-
-
- ;;; misc
- (define (home)
- (set! turtle-x 0)
- (set! turtle-y 0)
- (set! turtle-direction 270)
- (draw-turtle))
-
- (define (clear)
- (home)
- (down)
- (width 0)
- (colour 0)
- (turtle-canvas 'delete 'line 'text)
- (draw-turtle))
-
- (define (new)
- (clear)
- (turtle-canvas 'delete 'window))
-
- (define (screen-dump . file)
- (turtle-canvas 'postscript
- :file (if (null? file) "Screen-dump.ps" (car file))))
-
- (define (centre)
- (turtle-canvas 'xview 'moveto 0.37)
- (turtle-canvas 'yview 'moveto 0.37))
-
-
- ;;;conversion
- (define (d2r degrees)
- (/ degrees turtle-d2r))
-
- ;;; speed
- (define (speed . s)
- (if (null? s)
- turtle-speed
- (set! turtle-speed (car s))))
-
- (define (slow) (speed #t))
- (define (fast) (speed #f))
- (define (toggle-speed) (if turtle-speed (fast) (slow)))
-
- ;;; MACROS - move, moveto
- (define (move distance)
- (let ((oldpen (pen)))
- (go distance)
- (pen oldpen)))
-
- (define (moveto x y)
- (let ((oldpen (pen)))
- (goto x y)
- (pen oldpen)))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;
- ;;;; E x a m p l e s
- ;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
- ;; polygon
- (define (polygon n length)
- (do ((k 0 (+ k 1)))
- ((= k n))
- (turn (/ 360 n))
- (go length)))
-
- ;; polygon, with a functional parameter
- (define (fungon n length F)
- (do ((k 0 (+ k 1)))
- ((= k n))
- (turn (/ 360 n))
- (F length)))
-
- ;; Iterative Spiral
- (define (spiral angle length)
- (while (>= length 1)
- (go length)
- (turn angle)
- (set! length (- length 5))))
-
- ;; Recursive spiral
- (define (rspiral angle length)
- (when (>= length 1)
- (go length)
- (turn angle)
- (rspiral angle (- length 5))))
-
- ;; "Koch's" a single line - used in snowflake
- (define (koch order length)
- (if (or (<= order 1) (<= length 1))
- (go length)
- (begin
- (koch (- order 1) (/ length 3))
- (turn -60)
- (koch (- order 1) (/ length 3))
- (turn 120)
- (koch (- order 1) (/ length 3))
- (turn -60)
- (koch (- order 1) (/ length 3)))))
-
- ;; Koch's snowflake fractal
- (define (kochflake order length)
- (do ((k 0 (+ k 1)))
- ((= k 3))
- (turn 120)
- (koch order length)))
-
- ;; tricky version of kochflake
- (define (tricky-kochflake order length)
- (fungon 3 (lambda () (koch order length))))
-
- ;; Four sided koch
- (define (squarekoch order length)
- (if (or (<= order 1) (<= length 1))
- (go length)
- (begin
- (squarekoch (- order 1) (/ length 3))
- (turn -90)
- (squarekoch (- order 1) (/ length 3))
- (turn 90)
- (squarekoch (- order 1) (/ length 3))
- (turn 90)
- (squarekoch (- order 1) (/ length 3))
- (turn -90)
- (squarekoch (- order 1) (/ length 3)))))
-
- (define (squareflake order length)
- (do ((k 0 (+ k 1)))
- ((= k 4))
- (turn 90)
- (squarekoch order length)))
-
- ;; Fractal line
- (define (fracline order angle length)
- (if (< order 1)
- (go length)
- (let* ((ang (- [random (* 2 angle)] angle))
- (len (/ length (* 2 [cos (d2r ang)]))))
- (turn ang)
- (fracline (- order 1) angle len)
- (turn (- (* ang 2)))
- (fracline (- order 1) angle len)
- (turn ang))))
-
- ;; binary tree
- (define (bintree depth length angle)
- (when (> depth 0)
- (let ((saved (status)))
- (set! depth (- depth 1))
- (go length)
- (turn (- angle))
- (bintree depth length angle)
- (turn (+ angle 2))
- (bintree depth length angle)
- (status saved))))
-
- ;; C curve fractal
- (define (ccurv order length)
- (if (<= order 1)
- (go length)
- (begin
- (ccurv (- order 1) length)
- (turn 90)
- (ccurv (- order 1) length)
- (turn -90))))
-
- ;; Dragon curve fractal
- (define (dragon order length)
- (letrec ((dragon-aux (lambda (order length dirn)
- (if (<= order 1)
- (go length)
- (begin
- (dragon-aux (- order 1) length 90)
- (turn dirn)
- (dragon-aux (- order 1) length -90))))))
- (dragon-aux order length 90)))
-
- ;; Sierpinski's gasket
- (define (gasket order length)
- (when (> order 0)
- (do ((k 0 (+ k 1)))
- ((= k 3))
- (gasket (- order 1) (/ length 2))
- (go length)
- (turn 120))))
-
- ;; Sierpinski's carpet
- (define (carpet order length)
- (if (< order 1)
- (go length)
- (begin
- (carpet (- order 1) (/ length 3))
- (turn -90)
- (carpet (- order 1) (/ length 3))
- (turn 90)
- (carpet (- order 1) (/ length 3))
- (turn 90)
- (carpet (- order 1) (/ length 3))
- (let ((saved (status)))
- (carpet (- order 1) (/ length 3))
- (turn 90)
- (carpet (- order 1) (/ length 3))
- (turn 90)
- (carpet (- order 1) (/ length 3))
- (status saved)
- (turn -90)
- (carpet (- order 1) (/ length 3))))))
-
- ;; "Bendy" - simple fractal (C curve variation)
- (define (bendy order length)
- (if (< order 1)
- (go length)
- (begin
- (turn 30)
- (bendy (- order 1) (/ length 2))
- (turn -60)
- (bendy (- order 1) (/ length 2))
- (turn 30))))
-
- ;; "Squigly" - simple fractal (C curve variation)
- (define (squigly order length)
- (if (< order 1)
- (go length)
- (begin
- (turn 30)
- (squigly (- order 1) (/ length 4))
- (turn -60)
- (squigly (- order 1) (/ length 2))
- (turn 60)
- (squigly (- order 1) (/ length 4))
- (turn -30))))
-
- (define (randtree depth length angle branch)
- (when (>= depth 1)
- (let ((saved (status))
- (thisbranch (random branch)))
- (set! depth (- depth 1))
- (go (+ (random length) length))
- (turn (- (/ (* angle thisbranch) 4)))
- (do ((k 0 (+ k 1)))
- ((= k thisbranch))
- (turn (random angle))
- (randtree depth length angle branch))
- (status saved))))
-
- ;;windows-demo
- (define (windows-demo)
- (let ((S (scale (& turtle-canvas "scale"))))
- (show)
- (up)
- (goto -200 -200)
- (window S)
- (goto -150 -200)
- (window (button (& turtle-canvas ".spiral-button") :text "Spiral"
- :command (lambda () (spiral [S 'get] 100))))
- (goto -100 -200)
- (window [button (& turtle-canvas ".clear-button") :text "Clear" :command clear])
- (goto -50 -200)
- (window [button (& turtle-canvas ".home-button") :text "Home" :command home])
- (goto 180 -200)
- (window [button (& turtle-canvas ".quit-button") :text "Quit Demo"
- :fg "CadetBlue" :command (lambda () (exit))])
- (S 'set 45)
- (down)
- (home)))
-
- (define (item message demo)
- (clear)
- (up)
- (goto 0 220)
- (down)
- (Write message)
- (home)
- (demo))
-
- (define (run-demo)
- (item "Polygon"
- (lambda ()
- (do ((k 3 (+ k 1))) ((= k 12))
- (home) (polygon k 50))))
- (item "Lines"
- (lambda ()
- (do ((k 0 (+ k 1))) ((= k 16))
- (moveto 0 0) (turn 22.5) (width k) (go 200))))
-
- (item "Stipple"
- (lambda ()
- (width 15)
- (do ((k 0 (+ k 1))) ((= k 16))
- (moveto 0 0) (turn 22.5) (colour k) (go 200))))
-
- (item "Fractal lines"
- (lambda ()
- (do ((k 0 (+ k 1))) ((= k 7))
- (home) (fracline 6 40 200))))
-
- (item "Spiral" (lambda () (spiral 50 100)))
- (item "Recursive spiral" (lambda () (rspiral 89 100)))
- (item "Recursive spiral" (lambda () (rspiral -90 100)))
- (item "Koch flake" (lambda () (kochflake 3 150)))
- (item "Square flake" (lambda () (squareflake 3 150)))
- (item "Squigly" (lambda () (squigly 4 200)))
- (item "C curve" (lambda () (ccurv 6 20)))
- (item "Dragon" (lambda () (dragon 6 20)))
- (item "Gasket" (lambda () (gasket 6 200)))
- (item "Carpet" (lambda () (carpet 3 250)))
- (item "Binary tree" (lambda () (bintree 6 30 20)))
- (item "Random tree" (lambda () (randtree 4 20 30 6)))
- (item "Windows Demo" windows-demo))
-
-
-
- ;; Init part - Run the demo
- (expand-heap 50000)
- (set! *gc-verbose* #f)
-
- (turtle)
- (hide)
-
- (run-demo)
-